home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / uucp106d / part05 < prev    next >
Encoding:
Text File  |  1990-06-28  |  56.7 KB  |  2,621 lines

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i183: UUCP 1.06D - UNIX compatible uucp/news/mail system, Part05/12
  5. Message-ID: <12974@xanth.cs.odu.edu>
  6. Date: 28 Jun 90 12:22:42 GMT
  7. Sender: news@cs.odu.edu
  8. Reply-To: Matt Dillon <@uunet.uu.net:overload!dillon>
  9. Lines: 2607
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon>
  15. Posting-number: Volume 90, Issue 183
  16. Archive-name: unix/uucp-1.06d/part05
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 5 (of 12)."
  25. # Contents:  uucp2/src/anews/mscan.c uucp2/src/anews/news.c
  26. #   uucp2/src/anews/unpackmail.c uucp2/src/dmail/main.c
  27. #   uucp2/src/dmail/sub.c uucp2/src/lib/alias.c
  28. #   uucp2/src/news/postnews.c.OLD uucp2/src/sendmail/domain.c
  29. #   uucp2/src/unix/unshar.c
  30. # Wrapped by tadguy@xanth on Thu Jun 28 08:21:24 1990
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. if test -f 'uucp2/src/anews/mscan.c' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'uucp2/src/anews/mscan.c'\"
  34. else
  35. echo shar: Extracting \"'uucp2/src/anews/mscan.c'\" \(5263 characters\)
  36. sed "s/^X//" >'uucp2/src/anews/mscan.c' <<'END_OF_FILE'
  37. X
  38. X/*
  39. X *  MSCAN.C
  40. X *
  41. X * mscan - Scan directories and return a sorted list of file names,
  42. X *        one at a time.
  43. X *
  44. X *  This code originally taken from sysdep.c:
  45. X *
  46. X * (C) Copyright 1987 by John Gilmore
  47. X * Copying and use of this program are controlled by the terms of the Free
  48. X * Software Foundation's GNU Emacs General Public License.
  49. X *
  50. X * Amiga Changes Copyright 1988 by William Loftus.  All rights reserved.
  51. X *
  52. X * Rewrite for nlib Copyright 1990 by J. Gregory Noel.    All rights reserved.
  53. X */
  54. X
  55. X#include "news.h"
  56. X#include <ctype.h>
  57. X#include <getfiles.h>
  58. X#include <expand_path.h>
  59. X
  60. X#define GAP    2
  61. X
  62. Xextern char *NewsDir;        /* Path to news directory */
  63. Xstatic dir_list *files;     /* List of articles to be examined */
  64. Xstatic dir_list *curptr;    /* Pointer to current article */
  65. Xstatic char *curgroup;        /* Name of current group */
  66. X
  67. Xstatic int    /* select only files that are purely numeric */
  68. Xfilesel(char *a)
  69. X{
  70. X    while (*a != '\0') {
  71. X        if (!isdigit(*a))
  72. X            return 0;
  73. X        ++a;
  74. X    }
  75. X    return 1;
  76. X}
  77. X
  78. Xstatic int    /* sort based upon the numeric value of the filename */
  79. Xfilecmp(dir_list *a, dir_list *b)
  80. X{
  81. X    register long i;
  82. X
  83. X    i = atol(a->name + GAP) - atol(b->name + GAP);
  84. X    if (i != 0) return i > 0;
  85. X    return strcmp(a->name, b->name);
  86. X}
  87. X
  88. Xvoid        /* remove files marked for deletion */
  89. Xfree_directory(delart)
  90. Xint delart;
  91. X{
  92. X    register dir_list *p;
  93. X    register int last;
  94. X
  95. X    last = -1;
  96. X    while (p = files) {
  97. X    files = p->next;
  98. X    if (p->name[0]) {
  99. X        if (delart)
  100. X        remove(expand_path(curgroup, p->name + GAP));
  101. X    } else if (p->name[1])
  102. X        last = atoi(p->name + GAP);
  103. X    else if (last < 0)
  104. X        last = 0;
  105. X    free(p);
  106. X    }
  107. X    if (last >= 0) {
  108. X    register FILE *fp;
  109. X    if (fp = fopen(expand_path(curgroup, ".read"), "w")) {
  110. X        fprintf(fp, "%d", last);
  111. X        fclose(fp);
  112. X    }
  113. X    } else if (delart) {
  114. X    /* all files were deleted -- try to delete directory */
  115. X    remove(expand_path(curgroup, ".next"));
  116. X    remove(expand_path(curgroup, ".read"));
  117. X    rmdir(curgroup);
  118. X    }
  119. X    curptr = NULL;
  120. X    if (curgroup) {
  121. X    free(curgroup);
  122. X    curgroup = NULL;
  123. X    }
  124. X}
  125. X
  126. Xint        /* produce a list of articles in the group */
  127. Xscan_directory(char *dir)
  128. X{
  129. X    register dir_list *p;
  130. X    register int count = 0;
  131. X    register FILE *fp;
  132. X    int read;
  133. X    char name[100], newname[100];
  134. X    extern int unpackmail(char *dir, int count);
  135. X
  136. Xrecurse:
  137. X    free_directory(0);
  138. X    curgroup = strdup((dir == NULL) ? NewsDir : expand_path(NewsDir, dir));
  139. X    if (access(curgroup, 0) == -1) {
  140. X        free(curgroup), curgroup = NULL;
  141. X        return 0;
  142. X    }
  143. X
  144. X    if ((files = getfiles(curgroup, GAP, filesel, filecmp)) == NULL) {
  145. X        if (unpackmail(curgroup, 0) > 0) {
  146. X            /* return scan_directory(dir); */
  147. X            goto recurse;
  148. X        }
  149. X#ifdef NOTDEF    /* DON'T DELETE THE !#@$#@ DIRECTORY IDIOT  */
  150. X        /* no files in directory -- try to delete directory */
  151. X        remove(expand_path(curgroup, ".next"));
  152. X        remove(expand_path(curgroup, ".read"));
  153. X        rmdir(curgroup);
  154. X#endif
  155. X        return 0;
  156. X    }
  157. X
  158. X    read = 0;
  159. X    if ((fp = fopen(expand_path(curgroup, ".read"), "r")) != NULL) {
  160. X        fscanf(fp, "%d", &read);
  161. X        fclose(fp);
  162. X    }
  163. X
  164. X    for (p = files; p != NULL; p = p->next) {
  165. X        p->name[0] = 0;
  166. X        p->name[1] = (atoi(p->name + GAP) <= read);
  167. X        sprintf(name, "%s/%s", curgroup, p->name + GAP);
  168. X        sprintf(newname, "%s/%d", curgroup, ++count);
  169. X        if (strcmp(name, newname) != 0)
  170. X            if (rename(name, newname) == 0)
  171. X                sprintf(p->name + GAP, "%d", count);
  172. X    }
  173. X
  174. X    if (unpackmail(curgroup, count) > count)
  175. X        return scan_directory(dir);
  176. X
  177. X    if ((fp = fopen(expand_path(curgroup, ".next"), "w")) != NULL) {
  178. X        fprintf(fp, "%d", count + 1);
  179. X        fclose(fp);
  180. X    }
  181. X    return count;
  182. X}
  183. X
  184. Xchar *
  185. Xfirst_unread(void)
  186. X{
  187. X    register dir_list *p;
  188. X
  189. X    for (p = files; p != NULL; p = p->next) {
  190. X        if (p->name[1] == 0) {
  191. X            curptr = p;
  192. X            return p->name + GAP;
  193. X        }
  194. X    }
  195. X    curptr = NULL;
  196. X    return NULL;
  197. X}
  198. X
  199. Xint
  200. Xunread_count(void)
  201. X{
  202. X    register dir_list *p;
  203. X    register int count = 0;
  204. X
  205. X    for (p = files; p != NULL; p = p->next)
  206. X        if (p != curptr && p->name[1] == 0)
  207. X            ++count;
  208. X    return count;
  209. X}
  210. X
  211. Xchar *
  212. Xgoto_article(char *name)
  213. X{
  214. X    register dir_list *p;
  215. X
  216. X    for (p = files; p != NULL; p = p->next) {
  217. X        if (strcmp(p->name + GAP, name) == 0) {
  218. X            curptr = p;
  219. X            return p->name + GAP;
  220. X        }
  221. X    }
  222. X    curptr = NULL;
  223. X    return NULL;
  224. X}
  225. X
  226. Xchar *
  227. Xget_next_art(void)
  228. X{
  229. X    if (curptr == NULL)
  230. X        curptr = files;
  231. X    else
  232. X        curptr = curptr->next;
  233. X    return (curptr == NULL) ? NULL : curptr->name + GAP;
  234. X}
  235. X
  236. Xchar *
  237. Xget_prev_art(void)
  238. X{
  239. X    register dir_list *p;
  240. X
  241. X    if (curptr == NULL)
  242. X        return NULL;
  243. X    if (curptr == files)
  244. X        return curptr->name + GAP;
  245. X    for (p = files; p != NULL; p = p->next) {
  246. X        if (p->next == curptr) {
  247. X            curptr = p;
  248. X            return p->name + GAP;
  249. X        }
  250. X    }
  251. X    /* should never get here... */
  252. X    curptr = NULL;
  253. X    return NULL;
  254. X}
  255. X
  256. Xvoid
  257. Xrewind_arts(void)
  258. X{
  259. X    register dir_list *p;
  260. X
  261. X    for (p = files; p != NULL; p = p->next)
  262. X        if (p->name[0] == 0)
  263. X            p->name[1] = 0;
  264. X    curptr = NULL;
  265. X}
  266. X
  267. Xvoid
  268. Xmark_cur_art(int flag)
  269. X{
  270. X    if (curptr != NULL)
  271. X        curptr->name[1] = flag;
  272. X}
  273. X
  274. Xvoid
  275. Xdel_cur_art(int flag)
  276. X{
  277. X    if (curptr != NULL)
  278. X        curptr->name[0] = flag;
  279. X}
  280. X
  281. Xvoid
  282. Xhold_cur_art(void)
  283. X{
  284. X    if (curptr != NULL)
  285. X        curptr->name[1] = curptr->name[0];
  286. X}
  287. X
  288. X#ifdef TEST
  289. X#undef TEST
  290. X#include "unpackmail.c"
  291. Xchar *NewsDir;
  292. X
  293. Xmain(int argc, char **argv)
  294. X{
  295. X    register char *p;
  296. X
  297. X    NewsDir = GetConfigDir(UUNEWS);
  298. X    printf("%d articles:\n", scan_directory("mail.test"));
  299. X    while ((p = get_next_art()) != NULL)
  300. X        printf("%s ", p);
  301. X    putchar('\n');
  302. X    return 0;
  303. X}
  304. X#endif
  305. END_OF_FILE
  306. if test 5263 -ne `wc -c <'uucp2/src/anews/mscan.c'`; then
  307.     echo shar: \"'uucp2/src/anews/mscan.c'\" unpacked with wrong size!
  308. fi
  309. # end of 'uucp2/src/anews/mscan.c'
  310. fi
  311. if test -f 'uucp2/src/anews/news.c' -a "${1}" != "-c" ; then 
  312.   echo shar: Will not clobber existing file \"'uucp2/src/anews/news.c'\"
  313. else
  314. echo shar: Extracting \"'uucp2/src/anews/news.c'\" \(6709 characters\)
  315. sed "s/^X//" >'uucp2/src/anews/news.c' <<'END_OF_FILE'
  316. X
  317. X/*
  318. X *  ANEWS -r rows -c cols -p group
  319. X */
  320. X
  321. X#include "news.h"
  322. X#include <ctype.h>
  323. X#include <libraries/dos.h>
  324. X#include <getfiles.h>
  325. X
  326. XIDENT(".03");
  327. X
  328. X#define ON        scr_inverse_on()
  329. X#define OFF        scr_inverse_off()
  330. X#define Clear_eol    printf("\x9bK")
  331. X#define Clear_Screen    printf("\x9bH\x9bJ")
  332. X#define Cr        putchar('\r')
  333. X#define PROG_NAME    "Anews"
  334. X
  335. Xchar *NewsDir;
  336. Xchar fg, bg;
  337. X
  338. Xint NumRows = 22;
  339. Xint NumCols = 77;
  340. X
  341. Xdir_list *groups;
  342. X
  343. Xvoid
  344. Xinitgroups(void)
  345. X{
  346. X    dir_list *gp;
  347. X    int len;
  348. X    FILE *fp;
  349. X    char buf[50];
  350. X
  351. X    if (groups != NULL)
  352. X    return;
  353. X
  354. X    if ((fp = openlib("newsgroups")) == NULL) {
  355. X    puts("Couldn't open LIB/newsgroups file");
  356. X    exit(2);
  357. X    }
  358. X
  359. X    gp = (dir_list *)&groups;
  360. X    while (fgets(buf, (int)sizeof buf, fp) != NULL) {
  361. X    len = strlen(buf) - 1;
  362. X    buf[len] = '\0';
  363. X    if ((gp->next = (dir_list *)malloc(4 + len + 1)) == NULL) {
  364. X        puts("Malloc failed!");
  365. X        exit(4);
  366. X    }
  367. X    gp = gp->next;
  368. X    strcpy(gp->name, buf);
  369. X    }
  370. X    gp->next = NULL;
  371. X
  372. X    fclose(fp);
  373. X}
  374. X
  375. Xstatic char *
  376. Xng(register int i)
  377. X{
  378. X    register dir_list *gp;
  379. X    register int II = i;
  380. X    static char *NAME;
  381. X    static int I = -1;
  382. X
  383. X    if (i == I)
  384. X    return NAME;
  385. X
  386. X    for (gp = (dir_list *)&groups; (gp = gp->next) != NULL; ) {
  387. X    if (--i < 0) {
  388. X        I = II;
  389. X        return (NAME = gp->name);
  390. X    }
  391. X    }
  392. X    return NULL;
  393. X}
  394. X
  395. Xstatic char *GroupHelp[] = {
  396. X    "y/Y    Read this newsgroup (default)",
  397. X    "n/N    Skip this newsgroup",
  398. X    "-      Go back to previous news group",
  399. X    "^      Go back to first news group",
  400. X    "=      List article subjects in this newsgroup",
  401. X    "p      Post to this news group",
  402. X    "h/H/?  Display help",
  403. X    "q/Q    Quit to DOS\n",
  404. X    0
  405. X};
  406. X
  407. Xint
  408. Xmain(ac, av)
  409. Xchar **av;
  410. X{
  411. X    int ch, cnt, nbr;
  412. X    char *curgp;
  413. X    int found1 = 0;
  414. X    int current = -1;
  415. X    int old, last = 0;
  416. X    short i;
  417. X    short notdone = 1;
  418. X
  419. X    for (i = 1; i < ac; ++i) {
  420. X    char *ptr = av[i];
  421. X
  422. X    if (*ptr == '-') {
  423. X        ptr += 2;
  424. X        switch(ptr[-1]) {
  425. X        case 'p':
  426. X        if (*ptr)
  427. X            reply(0, NULL, ptr);
  428. X        else
  429. X            reply(0, NULL, av[++i]);
  430. X        notdone = 0;
  431. X        break;
  432. X        case 'r':
  433. X        if (*ptr)
  434. X            NumRows = atoi(ptr);
  435. X        else
  436. X            NumRows = atoi(av[++i]);
  437. X        break;
  438. X        case 'c':
  439. X        if (*ptr)
  440. X            NumCols = atoi(ptr);
  441. X        else
  442. X            NumCols = atoi(av[++i]);
  443. X        break;
  444. X        }
  445. X    }
  446. X    }
  447. X
  448. X    if (notdone == 0) {
  449. X    cooked(stdin);
  450. X    exit(1);
  451. X    }
  452. X
  453. X    init();
  454. X
  455. X    for (;;) {
  456. X    NewGroup:
  457. X    if ((curgp = ng(++current)) == NULL) {
  458. X        if (!found1) {
  459. X        puts("No News, use 'anews -p group' to post new articles");
  460. X        do_quit();
  461. X        } else {
  462. X        found1 = 0, current = -1;
  463. X        continue;
  464. X        }
  465. X    }
  466. X
  467. X    while ((nbr = scan_directory(curgp)) != 0) {
  468. X        old = last, last = current;
  469. X        RepeatGroup:
  470. X        Cr, Clear_eol;
  471. X        ON;
  472. X        cnt = unread_count();
  473. X        printf("%d articles in %s (%d unread)? [%s]",
  474. X        nbr, curgp, cnt, (cnt == 0) ? "n/y" : "y/n"
  475. X        );
  476. X        OFF;
  477. X        putchar(' ');
  478. X        ch = rawch();
  479. X        if (ch == ' ')
  480. X        ch = (cnt == 0) ? 'n' : 'y';
  481. X
  482. X        switch (ch) {
  483. X        case 'y':
  484. X        case 'Y':
  485. X        ++found1;
  486. X        if (cnt == 0)
  487. X            rewind_arts();
  488. X        ch = readgroup(curgp);
  489. X        if (ch == 'q')
  490. X            do_quit();
  491. X        if (ch == '$')
  492. X            goto NewGroup;
  493. X        if (ch)
  494. X            break;
  495. X        /* Fall through to... */
  496. X        case 'q':
  497. X        case 'Q':
  498. X        putchar('\n');
  499. X        do_quit();
  500. X        case 'n':
  501. X        case 'N':
  502. X        putchar('\n');
  503. X        goto NewGroup;
  504. X        case '^':
  505. X        current = -1;
  506. X        goto NewGroup;
  507. X        case '-':
  508. X        current = old - 1;
  509. X        goto NewGroup;
  510. X/* FIXME add case to go directly to a specific (named) news group */
  511. X        case 'h':
  512. X        case 'H':
  513. X        case '?':
  514. X        do_help(GroupHelp);
  515. X        goto RepeatGroup;
  516. X        case '=':
  517. X        putchar('\n');
  518. X        scan_subjects(curgp);
  519. X        goto RepeatGroup;
  520. X        case 'p':
  521. X        putchar('\n');
  522. X        reply(0, NULL, curgp);
  523. X        goto RepeatGroup;
  524. X        }
  525. X    }
  526. X    }
  527. X    return 0;
  528. X}
  529. X
  530. Xchar *
  531. XGet_Env(char *envar, char *def)
  532. X{
  533. X    char *p, *eptr;
  534. X
  535. X    if ((p = getenv(envar)) != NULL) {
  536. X    eptr = (char *)malloc(strlen(p) + 1);
  537. X    strcpy(eptr, p);
  538. X    } else {
  539. X    eptr = def;
  540. X    }
  541. X    return(eptr);
  542. X}
  543. X
  544. Xvoid
  545. Xinit()
  546. X{
  547. X    NewsDir = GetConfigDir(UUNEWS);
  548. X    if (access(NewsDir, 0) == -1) {
  549. X    printf("FATAL - couldn't access %s\n", NewsDir);
  550. X    exit(1);
  551. X    }
  552. X    fg = *Get_Env("FG", "8");
  553. X    bg = *Get_Env("BG", "0");
  554. X    initgroups();
  555. X}
  556. X
  557. Xstatic char buf[BUFSIZ];
  558. X
  559. Xchar *
  560. Xsubs(char *newsfile)
  561. X{
  562. X    FILE *fp;
  563. X    int j;
  564. X
  565. X    if ((fp = fopen(newsfile, "r")) == NULL) {
  566. X    printf("Couldn't open %s\n", newsfile);
  567. X    return(NULL);
  568. X    }
  569. X    j = 0;
  570. X    while ( (j++<50) && (fgets(buf, (int)sizeof buf, fp) != NULL)) {
  571. X    if (strncmp("Subject:", buf, 8) == 0) {
  572. X        buf[strlen(buf)-1] = '\0';
  573. X        fclose(fp);
  574. X        return (buf + 8);
  575. X    }
  576. X    }
  577. X    fclose(fp);
  578. X    return NULL;
  579. X}
  580. X
  581. Xvoid
  582. Xdo_quit(void)
  583. X{
  584. X    exit(0);
  585. X}
  586. X
  587. Xvoid
  588. Xdo_help(char **pp)
  589. X{
  590. X    printf("\x9bH\x9bJ\033[0;1;33;40m\r");
  591. X    do {
  592. X    puts(*pp);
  593. X    } while (*++pp != NULL);
  594. X    printf("\033[0;31;40m");
  595. X}
  596. X
  597. Xchar *
  598. Xart2file(char *group, char *art)
  599. X{
  600. X    static char path[128];
  601. X
  602. X    sprintf(path, "%s/%s", expand_path(NewsDir, group), art);
  603. X    return path;
  604. X}
  605. X
  606. Xint
  607. Xreadgroup(char *group)
  608. X{
  609. X    register int ch;
  610. X    register char *name;
  611. X    char newname[128];
  612. X
  613. X    while (name = first_unread()) {
  614. X    named_art:
  615. X    switch (ch = showart(group, name)) {
  616. X    case 'd':
  617. X    case 'D':
  618. X        del_cur_art(1);
  619. X        /* fall through to... */
  620. X
  621. X    case 'n':
  622. X    case 'N':
  623. X        mark_cur_art(1);
  624. X        break;
  625. X
  626. X    case 'q':
  627. X        free_directory(1);
  628. X        return('x');
  629. X    case 'Q':
  630. X        free_directory(0);
  631. X        return ('x');
  632. X
  633. X    case '$':
  634. X        free_directory(1);
  635. X        return '$';
  636. X
  637. X    case '-':
  638. X        name = get_prev_art();
  639. X        goto named_art;
  640. X
  641. X    case '^':
  642. X        rewind_arts();
  643. X        break;
  644. X
  645. X    case '0':
  646. X    case '1':
  647. X    case '2':
  648. X    case '3':
  649. X    case '4':
  650. X    case '5':
  651. X    case '6':
  652. X    case '7':
  653. X    case '8':
  654. X    case '9':
  655. X        newname[0] = ch;
  656. X        ON;
  657. X        printf("Goto Article");
  658. X        OFF;
  659. X        printf(" #%c", ch);
  660. X        fflush(stdout);
  661. X        gets(newname+1);
  662. X
  663. X        if ((name = goto_article(newname)) == NULL) {
  664. X        /* FIXME -- handle illegal article */
  665. X        break;    /* DEBUG */
  666. X        }
  667. X        goto named_art;
  668. X
  669. X    case '.':
  670. X    case '>':
  671. X    case ',':
  672. X    case '<':
  673. X        for(;;) {
  674. X        printf("\r             #%s\t%-50s", name, subs(art2file(group, name)));
  675. X        ON;
  676. X        printf("\rGoto Article");
  677. X        OFF;
  678. X        switch (rawch()) {
  679. X        case '>':
  680. X        case '.':
  681. X            if ((name = get_next_art()) == NULL) {
  682. X            /* wrap around to begining */
  683. X            name = get_next_art();
  684. X            }
  685. X            break;
  686. X        case ',':
  687. X        case '<':
  688. X            name = get_prev_art();
  689. X            break;
  690. X        default:
  691. X            goto named_art;
  692. X        }
  693. X        }
  694. X    default:
  695. X        break;
  696. X    }
  697. X    }
  698. X    free_directory(1);
  699. X    return ('n');
  700. X}
  701. X
  702. Xvoid
  703. Xscr_inverse_on(void)
  704. X{
  705. X    printf("\x9b\x37;3%c;4%cm", fg, bg);
  706. X}
  707. X
  708. Xvoid
  709. Xscr_inverse_off(void)
  710. X{
  711. X    printf("\x9b\x30;33;40m\033[0m");
  712. X}
  713. X
  714. Xrawch(void)
  715. X{
  716. X    register int ch;
  717. X
  718. X    fflush(stdout);
  719. X    raw(stdin);
  720. X    ch = getchar();
  721. X    cooked(stdin);
  722. X    return (ch);
  723. X}
  724. X
  725. END_OF_FILE
  726. if test 6709 -ne `wc -c <'uucp2/src/anews/news.c'`; then
  727.     echo shar: \"'uucp2/src/anews/news.c'\" unpacked with wrong size!
  728. fi
  729. # end of 'uucp2/src/anews/news.c'
  730. fi
  731. if test -f 'uucp2/src/anews/unpackmail.c' -a "${1}" != "-c" ; then 
  732.   echo shar: Will not clobber existing file \"'uucp2/src/anews/unpackmail.c'\"
  733. else
  734. echo shar: Extracting \"'uucp2/src/anews/unpackmail.c'\" \(5525 characters\)
  735. sed "s/^X//" >'uucp2/src/anews/unpackmail.c' <<'END_OF_FILE'
  736. X
  737. X/*
  738. X *  UNPACKMAIL.C
  739. X */
  740. X
  741. X#include "news.h"
  742. X#include <expand_path.h>
  743. X#include <ctype.h>
  744. X
  745. Xstatic FILE *mp;
  746. X
  747. Xstatic void
  748. XCloseOldFile(void)
  749. X{
  750. X    if (mp) {
  751. X    fflush(mp);
  752. X    if (fclose(mp) != 0) {
  753. X        printf("FATAL -- I/O error while writing message\n");
  754. X        exit(20);
  755. X    }
  756. X    mp = NULL;
  757. X    }
  758. X}
  759. X
  760. Xstatic int
  761. XNewFile(char *dir, int count)
  762. X{
  763. X    char namebuf[64];
  764. X
  765. X    CloseOldFile();
  766. X
  767. X    do {
  768. X    sprintf(namebuf, "%s/%d", dir, ++count);
  769. X    } while (access(namebuf, 0) == 0);
  770. X
  771. X    if ((mp = fopen(namebuf, "w")) == NULL) {
  772. X    printf("FATAL -- can't create %s to hold new message\n", namebuf);
  773. X    exit(10);
  774. X    }
  775. X    printf("%4d: ", count);
  776. X    return (count);
  777. X}
  778. X
  779. Xstatic void
  780. Xcopyline(register char *buf, FILE *fp)
  781. X{
  782. X    register int c;
  783. X
  784. X    if (mp == NULL)
  785. X    return;
  786. X
  787. X    while (*buf != '\0') {
  788. X    putc(*buf, mp);
  789. X    if (*buf == '\n')
  790. X        return;
  791. X    ++buf;
  792. X    }
  793. X    while ((c = getc(fp)) != EOF) {
  794. X    putc(c, mp);
  795. X    if (c == '\n')
  796. X        return;
  797. X    }
  798. X}
  799. X
  800. Xstatic int
  801. Xreal_from(char *buffer, char *who)
  802. X{
  803. X    /*
  804. X     * returns true if 's' has the seven 'from' fields,
  805. X     * initializing the who to the sender
  806. X     * also returns true if has dmail ARCHIVE flag
  807. X     */
  808. X    char fld3[20], fld7[20];
  809. X
  810. X    if (strncmp(buffer, "From ", 5) != 0)
  811. X    return (0);
  812. X
  813. X    fld7[0] = '\0';
  814. X    sscanf(buffer, "%*s %s %s %*s %*s %*s %s", who, fld3, fld7);
  815. X    if (fld7[0] != '\0')
  816. X    return (1);
  817. X    if (strcmp(fld3, "(ARCHIVE)") != 0)
  818. X    return (0);
  819. X    strcpy(who, fld3);
  820. X    return (1);
  821. X}
  822. X
  823. Xstatic void
  824. Xforwarded(char *buffer, char *who)
  825. X{
  826. X    /*
  827. X     * change 'from' and date fields to reflect the ORIGINATOR of
  828. X     * the message by iteratively parsing the >From fields...
  829. X     */
  830. X    char machine[80], buff[80];
  831. X
  832. X    machine[0] = '\0';
  833. X    sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s", who, machine);
  834. X
  835. X    if (machine[0] == '\0') /* try for srm address */
  836. X    sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s", who, machine);
  837. X
  838. X    if (machine[0] == '\0')
  839. X    sprintf(buff, "anonymous");
  840. X    else
  841. X    sprintf(buff, "%s!%s", machine, who);
  842. X
  843. X    strncpy(who, buff, 80);
  844. X}
  845. X
  846. Xstatic void
  847. Xremove_first_word(char *dest, char *string)
  848. X{
  849. X    /*
  850. X     * Removes first word of string, i.e., up to first non-white space
  851. X     * following a white space, and copies it to the destination.
  852. X     */
  853. X    while (!isspace(*string))
  854. X    ++string;
  855. X    while (isspace(*string))
  856. X    ++string;
  857. X    while (*dest++ = *string++)
  858. X    ;
  859. X    if (dest[-2] == '\n')
  860. X    dest[-2] = '\0';
  861. X}
  862. X
  863. Xstatic void
  864. Xshow_header(char *from, char *subject)
  865. X{
  866. X    /*
  867. X     * output header in clean format, including abbreviation
  868. X     * of return address if more than one machine name is
  869. X     * contained within it!
  870. X     */
  871. X    register char *p, *q, *r;
  872. X
  873. X#ifdef PREFER_UUCP
  874. X    if (chloc(from, '!') != -1 && chloc(from, '@') > 0) {
  875. X    for (p=from; *p != '@'; p++)
  876. X        ;
  877. X    *p = '\0';
  878. X    }
  879. X#endif
  880. X
  881. X    p = from;
  882. X    q = from;      /* find address portion */
  883. X    while ((r = strchr(q, '!')) != NULL) {
  884. X    p = q;
  885. X    q = r + 1;
  886. X    }
  887. X
  888. X    printf("%-30s  %s\n", p, subject);
  889. X}
  890. X
  891. Xstatic void
  892. Xparse_arpa_from(char *buffer, char *newfrom)
  893. X{
  894. X    /*
  895. X     * Try to parse the 'From:' line given... It can be in one of
  896. X     * two formats:
  897. X     *        From: Dave Taylor <hpcnou!dat>
  898. X     * or   From: hpcnou!dat (Dave Taylor)
  899. X     * Change 'newfrom' ONLY if sucessfully parsed this entry and
  900. X     * the resulting name is non-null!
  901. X     */
  902. X    register char *p, *q;
  903. X    register int i;
  904. X
  905. X    if (*(q = buffer + strlen(buffer) - 1) == '>') {
  906. X        p = buffer + 6, q = p;        /* skip "From: " */
  907. X        do {
  908. X        ++q;
  909. X        } while (*q != '\0' && *q != '<' && *q != '(');
  910. X    } else if (*q == ')') {
  911. X        p = q;
  912. X        do {
  913. X        --p;
  914. X        } while ((p > buffer + 5) && *p != '(' && *p != '<');
  915. X    } else
  916. X    return;
  917. X
  918. X    if (p >= q)
  919. X    return;
  920. X
  921. X    /* remove leading spaces... */
  922. X    while (isspace(*++p))
  923. X    ;
  924. X
  925. X    /* remove trailing spaces... */
  926. X    while (isspace(*--q))
  927. X    ;
  928. X
  929. X    /* if anything is left, let's change 'from' value! */
  930. X    if (p >= q)
  931. X    return;
  932. X    i = p - q + 1;
  933. X    strncpy(newfrom, p, i)[i] = '\0';
  934. X}
  935. X
  936. Xstatic char buffer[1000];
  937. Xstatic char from_whom[512], subject[512];
  938. X
  939. Xint
  940. Xunpackmail(char *dir, int count)
  941. X{
  942. X    register FILE *fp;
  943. X    register char *mailfile;
  944. X
  945. X    if (access(mailfile = expand_path(dir, ".mailfile"), 0) != 0)
  946. X    return count;
  947. X    if ((fp = fopen(mailfile, "r")) == NULL)
  948. X    return count;
  949. X    mailfile = fgets(buffer, (int)sizeof buffer, fp);
  950. X    fclose(fp);
  951. X    if (mailfile == NULL)
  952. X    return count;
  953. X    if ((mailfile = strchr(buffer, '\n')) != NULL)
  954. X    *mailfile = '\0';
  955. X    if ((fp = fopen(buffer, "r")) == NULL)
  956. X    return count;
  957. X    mailfile = strdup(buffer);
  958. X
  959. X    printf("New mail:\n");
  960. X    mp = NULL;
  961. X    while (fgets(buffer, (int)sizeof buffer, fp) != NULL) {
  962. X    if (real_from(buffer, from_whom)) {
  963. X        count = NewFile(dir, count);
  964. X    } else if (from_whom[0] != '\0') {
  965. X        if (strncmp(buffer, ">From ", 6) == 0) {
  966. X        forwarded(buffer, from_whom);
  967. X        } else if (strncmp(buffer, "Subject:", 8) == 0 || strncmp(buffer, "Re:", 3) == 0) {
  968. X        if (subject[0] == '\0')
  969. X            remove_first_word(subject, buffer);
  970. X        } else if (strncmp(buffer, "From:", 5) == 0)
  971. X        parse_arpa_from(buffer, from_whom);
  972. X        else if (buffer[0] == '\n') {
  973. X        show_header(from_whom, subject);
  974. X        from_whom[0] = 0, subject[0] = 0;
  975. X        }
  976. X    }
  977. X    copyline(buffer, fp);
  978. X    }
  979. X    fclose(fp);
  980. X    CloseOldFile();
  981. X
  982. X#ifndef TEST
  983. X    remove(mailfile);
  984. X#else
  985. X    printf("remove(%s)\n", mailfile);
  986. X#endif
  987. X    free(mailfile);
  988. X    return count;
  989. X}
  990. X
  991. X#ifdef TEST
  992. Xmain(int argc, char **argv)
  993. X{
  994. X    printf("New value of count is %d\n", unpackmail("UUNEWS:mail.test", 9));
  995. X    return 0;
  996. X}
  997. X#endif
  998. X
  999. END_OF_FILE
  1000. if test 5525 -ne `wc -c <'uucp2/src/anews/unpackmail.c'`; then
  1001.     echo shar: \"'uucp2/src/anews/unpackmail.c'\" unpacked with wrong size!
  1002. fi
  1003. # end of 'uucp2/src/anews/unpackmail.c'
  1004. fi
  1005. if test -f 'uucp2/src/dmail/main.c' -a "${1}" != "-c" ; then 
  1006.   echo shar: Will not clobber existing file \"'uucp2/src/dmail/main.c'\"
  1007. else
  1008. echo shar: Extracting \"'uucp2/src/dmail/main.c'\" \(6263 characters\)
  1009. sed "s/^X//" >'uucp2/src/dmail/main.c' <<'END_OF_FILE'
  1010. X
  1011. X/*
  1012. X * MAIN.C
  1013. X *
  1014. X *  $Header: Beta:src/uucp/src/dmail/RCS/main.c,v 1.1 90/02/02 12:03:43 dillon Exp Locker: dillon $
  1015. X *
  1016. X *  (C) Copyright 1985-1990 by Matthew Dillon,  All Rights Reserved.
  1017. X *
  1018. X *  Global Routines:    MAIN()
  1019. X *            INIT()
  1020. X *            SIG_HANDLE()
  1021. X *
  1022. X *  Static Routines:    none.
  1023. X */
  1024. X
  1025. X#include <pwd.h>
  1026. X#include <stdio.h>
  1027. X#include <signal.h>
  1028. X#include <sys/types.h>
  1029. X#include <sys/stat.h>
  1030. X#include <config.h>
  1031. X#include "version.h"
  1032. X
  1033. X#include "dmail.h"
  1034. X
  1035. XIDENT(".04");
  1036. Xchar *dillon_cpr = DCOPYRIGHT;
  1037. X
  1038. X#define MAILHOME MakeConfigPath(UUMAIL, "")
  1039. X#define MBOX     MakeConfigPath(UUMAIL, "mbox")
  1040. X#define ALT_MBOX MakeConfigPath(UUMAIL, ".mbox")
  1041. X#define MAILRC     MakeConfigPath(UULIB, ".dmailrc")
  1042. X#define VISUAL     GetConfig(EDITOR, "dme")
  1043. X
  1044. Xvoid  init();
  1045. X
  1046. Xmain(argc, argv)
  1047. Xchar *argv[];
  1048. X{
  1049. X    int i, next, Retry;
  1050. X    int fop = 0, oop = 0;
  1051. X    int rcload = 1;
  1052. X    int options = 1;
  1053. X    int no_mail_overide = 0;
  1054. X    int nc = 0;
  1055. X    static int nameslist[128];
  1056. X    char *rcname;
  1057. X
  1058. X    if (push_base())
  1059. X    done (1);
  1060. X
  1061. X    init();
  1062. X    rcname = malloc (strlen(home_dir) + strlen(MAILRC) + 2);
  1063. X#ifdef AMIGA
  1064. X    rcname[0] = 0;
  1065. X#else
  1066. X    strcpy (rcname, home_dir);
  1067. X    strcat (rcname, "/");
  1068. X#endif
  1069. X    strcat (rcname, MAILRC);
  1070. X    for (i = 1; i < argc; ++i) {
  1071. X    next = 0;
  1072. X    if ((*argv[i] == '-') && options) {
  1073. X        if (*(argv[i] + 1) == '\0') {
  1074. X        options = 0;
  1075. X        continue;
  1076. X        }
  1077. X        while (*++argv[i]) {
  1078. X        switch (*argv[i]) {
  1079. X        case 'S':
  1080. X            lmessage_overide = 1;
  1081. X            break;
  1082. X        case 'O':
  1083. X            no_mail_overide = 1;
  1084. X            break;
  1085. X        case 'l':
  1086. X            rcload  = 1;
  1087. X            if (i + 1 < argc  &&  *argv[i + 1] != '-') {
  1088. X            xfree (rcname);
  1089. X            oop = 1;
  1090. X            ++i;
  1091. X            ++next;
  1092. X            rcname = malloc (strlen (argv[i]) + 1);
  1093. X            strcpy (rcname, argv[i]);
  1094. X            }
  1095. X            break;
  1096. X        case 'L':
  1097. X            rcload = 0;
  1098. X            break;
  1099. X        case 'D':
  1100. X            XDebug = 1;
  1101. X            break;
  1102. X        case 'F':
  1103. X            if (++i < argc) {
  1104. X            add_extra (argv[i]);
  1105. X            } else {
  1106. X            puts (" -F Requires Field argument");
  1107. X            exit (1);
  1108. X            }
  1109. X            ++next;
  1110. X            break;
  1111. X        case 'v':
  1112. X            set_var (LEVEL_SET, "verbose", "");
  1113. X            break;
  1114. X        case 'o':
  1115. X            xfree (output_file);
  1116. X            if (i + 1 < argc  &&  *argv[i + 1] != '-') {
  1117. X            oop = 1;
  1118. X            ++i;
  1119. X            ++next;
  1120. X            output_file = malloc (strlen (argv[i]) + 1);
  1121. X            strcpy (output_file, argv[i]);
  1122. X            } else {
  1123. X            oop = -1;
  1124. X            output_file = malloc (strlen(home_dir) +
  1125. X                strlen(ALT_MBOX) + 2);
  1126. X#ifdef AMIGA
  1127. X            strcpy (output_file, ALT_MBOX);
  1128. X#else
  1129. X            sprintf (output_file, "%s/%s", home_dir, ALT_MBOX);
  1130. X#endif
  1131. X            }
  1132. X            break;
  1133. X        case 'f':
  1134. X            if (i + 1 < argc  &&  *argv[i + 1] != '-') {
  1135. X            fop = 1;
  1136. X            ++i;
  1137. X            ++next;
  1138. X            mail_file = realloc (mail_file, strlen (argv[i]) + 1);
  1139. X            strcpy (mail_file, argv[i]);
  1140. X            } else {
  1141. X            fop = -1;
  1142. X            mail_file = realloc (mail_file,
  1143. X                strlen(home_dir) + strlen(MBOX) + 2);
  1144. X#ifdef AMIGA
  1145. X            strcpy (mail_file, MBOX);
  1146. X#else
  1147. X            sprintf (mail_file, "%s/%s", home_dir, MBOX);
  1148. X#endif
  1149. X            }
  1150. X            break;
  1151. X        default:
  1152. X            puts ("dmail: Bad argument");
  1153. X            puts ("dmail -O      then 'help' for help.");
  1154. X            done (1);
  1155. X        }
  1156. X        if (next)
  1157. X            break;
  1158. X        }
  1159. X    } else {
  1160. X        No_load_mail = 1;
  1161. X        nameslist[nc++] = i;
  1162. X    }
  1163. X    }
  1164. X    if (oop == -1  &&  fop == -1) {
  1165. X    mail_file = realloc (mail_file, strlen(output_file) + 1);
  1166. X    strcpy (mail_file, output_file);
  1167. X    }
  1168. Xends:
  1169. X    initial_load_mail();
  1170. X    m_select (Nulav, M_RESET);
  1171. X    Current = indexof (1);
  1172. X    if (nc)
  1173. X    set_var (LEVEL_SET, "comlinemail", "");
  1174. X    if (rcload) {
  1175. X    ac = 2;
  1176. X    av[1] = rcname;
  1177. X    do_source(rcname, 1);
  1178. X    }
  1179. X    if (nc) {
  1180. X    av[0] = "mail";
  1181. X    for (i = 0; i < nc; ++i)
  1182. X        av[i + 1] = argv[nameslist[i]];
  1183. X    ac = nc + 1;
  1184. X    do_reply ("", R_MAIL);
  1185. X    done (0);
  1186. X    }
  1187. X    if (Entries + no_mail_overide == 0) {
  1188. X    printf ("\nNO MAIL for %s\n\n", user_name);
  1189. X    return;
  1190. X    }
  1191. X    printf ("\nRF %-20s   WF %-20s\n", mail_file, output_file);
  1192. X    do {
  1193. X    Retry = 20;
  1194. X    pop_base();
  1195. Xloop:
  1196. X    if (push_base()) {
  1197. X        pop_base();
  1198. X        if (XDebug)
  1199. X        printf ("TOP LEVEL INTR, Level: %d\n", Longstack);
  1200. X        if (--Retry == 0)
  1201. X        done (1);
  1202. X        puts ("");
  1203. X        goto loop;
  1204. X    }
  1205. X    check_new_mail();
  1206. X    } while (do_command() > 0);
  1207. X
  1208. X    return(0);
  1209. X}
  1210. X
  1211. Xvoid
  1212. Xinit()
  1213. X{
  1214. X    char *str;
  1215. X    struct passwd *passwd;
  1216. X    extern int sig_handle();
  1217. X
  1218. X    Entry = (struct ENTRY *)malloc (sizeof(*Entry));
  1219. X    Entry->status = Entry->no = Entry->fpos = 0;
  1220. X    passwd = getpwuid(getuid());
  1221. X    if (passwd == NULL) {
  1222. X    printf("DMail, unable to get passwd entry for uid %d\n", getuid());
  1223. X    exit(1);
  1224. X    }
  1225. X    user_name    = malloc (strlen(passwd->pw_name) + 1);
  1226. X    home_dir    = malloc (strlen(passwd->pw_dir) + 1);
  1227. X    visual    = malloc (strlen(VISUAL) + 1);
  1228. X    strcpy  (visual     , VISUAL);
  1229. X    strcpy  (user_name, passwd->pw_name);
  1230. X    strcpy  (home_dir , passwd->pw_dir);
  1231. X#ifdef AMIGA
  1232. X    if (str = FindConfig(HOME))
  1233. X    strcpy ((home_dir = realloc (home_dir, strlen(str) + 1)), str);
  1234. X    if (str = FindConfig(USERNAME))
  1235. X    strcpy ((user_name = realloc (user_name, strlen(str) + 1)), str);
  1236. X    if (str = FindConfig(EDITOR))
  1237. X    strcpy ((visual = realloc (visual, strlen(str) + 1)), str);
  1238. X
  1239. X    if (str = MallocEnviro("USER"))
  1240. X    user_name = str;
  1241. X
  1242. X#else
  1243. X    if ((str = getenv ("HOME")) != NULL)
  1244. X    strcpy ((home_dir = realloc (home_dir, strlen(str) + 1)), str);
  1245. X    if ((str = getenv ("USER")) != NULL)
  1246. X    strcpy ((user_name = realloc (user_name, strlen(str) + 1)), str);
  1247. X    if ((str = getenv ("VISUAL")) != NULL)
  1248. X    strcpy ((visual = realloc (visual, strlen(str) + 1)), str);
  1249. X#endif
  1250. X    mail_file    = malloc (strlen(MAILHOME) + strlen(user_name) + 1);
  1251. X    sprintf (mail_file  , "%s%s", MAILHOME, user_name);
  1252. X    output_file = malloc (strlen(home_dir) + 2 + strlen(MBOX) + 1);
  1253. X#ifdef AMIGA
  1254. X    strcpy(output_file, MBOX);
  1255. X#else
  1256. X    sprintf (output_file, "%s/%s", home_dir, MBOX);
  1257. X#endif
  1258. X    fix_globals();
  1259. X#ifdef UNIX
  1260. X    signal (SIGHUP, sig_handle);
  1261. X    signal (SIGINT, sig_handle);
  1262. X    signal (SIGPIPE, SIG_IGN);
  1263. X#endif
  1264. X#ifdef AMIGA
  1265. X    signal (SIGINT, sig_handle);
  1266. X#endif
  1267. X}
  1268. X
  1269. Xsig_handle()
  1270. X{
  1271. X#ifdef UNIX
  1272. X    int mask = sigblock (0);
  1273. X
  1274. X    sigsetmask (mask & ~((1 << SIGHUP) | (1 << SIGINT)));
  1275. X#endif
  1276. X#ifdef AMIGA
  1277. X    signal (SIGINT, sig_handle);    /*  reload signal */
  1278. X#endif
  1279. X    if (Longstack  &&  !Breakstack)
  1280. X    longjmp (env[Longstack], 1);
  1281. X    return(0);
  1282. X}
  1283. X
  1284. Xget_inode(file)
  1285. Xchar *file;
  1286. X{
  1287. X    struct stat stats;
  1288. X
  1289. X    if (stat (file, &stats) < 0)
  1290. X    return (-1);
  1291. X    return (stats.st_ino);
  1292. X}
  1293. X
  1294. END_OF_FILE
  1295. if test 6263 -ne `wc -c <'uucp2/src/dmail/main.c'`; then
  1296.     echo shar: \"'uucp2/src/dmail/main.c'\" unpacked with wrong size!
  1297. fi
  1298. # end of 'uucp2/src/dmail/main.c'
  1299. fi
  1300. if test -f 'uucp2/src/dmail/sub.c' -a "${1}" != "-c" ; then 
  1301.   echo shar: Will not clobber existing file \"'uucp2/src/dmail/sub.c'\"
  1302. else
  1303. echo shar: Extracting \"'uucp2/src/dmail/sub.c'\" \(5006 characters\)
  1304. sed "s/^X//" >'uucp2/src/dmail/sub.c' <<'END_OF_FILE'
  1305. X
  1306. X/*
  1307. X * SUB.C
  1308. X *
  1309. X *  $Header: Beta:src/uucp/src/dmail/RCS/sub.c,v 1.1 90/02/02 12:03:38 dillon Exp Locker: dillon $
  1310. X *
  1311. X *  (C) Copyright 1985-1990 by Matthew Dillon,  All Rights Reserved.
  1312. X *
  1313. X *  Global Routines:    INDEXOF()
  1314. X *            SIG()
  1315. X *            POSITION_CURRENT()
  1316. X *            SKIP_TO_DATE()
  1317. X *            GET_FIELD()
  1318. X *            COMPILE_FIELD()
  1319. X *            ISFROM()
  1320. X *            XSTRNCMP()
  1321. X *            NEXT_WORD()
  1322. X *            DONE()
  1323. X *
  1324. X */
  1325. X
  1326. X#include <signal.h>
  1327. X#include <stdio.h>
  1328. X#include "dmail.h"
  1329. X#include "config.h"
  1330. X
  1331. X#ifdef UNIX
  1332. Xextern FILE *popen();
  1333. X#endif
  1334. X
  1335. Xxfree(ptr)
  1336. Xchar *ptr;
  1337. X{
  1338. X    static char *sptr;
  1339. X
  1340. X    if (sptr)
  1341. X    free (sptr);
  1342. X    sptr = ptr;
  1343. X    return (1);
  1344. X}
  1345. X
  1346. X
  1347. Xindexof(num)
  1348. Xregister int num;
  1349. X{
  1350. X    register int i, last;
  1351. X
  1352. X    if (num < 1)
  1353. X    num = -1;
  1354. X    for (last = -1, i = 0; i < Entries; ++i) {
  1355. X    if (Entry[i].no) {
  1356. X        last = i;
  1357. X        if (Entry[i].no == num)
  1358. X        return (i);
  1359. X    }
  1360. X    }
  1361. X    if (num == -1  &&  last >= 0)
  1362. X    return (last);
  1363. X    return (-1);
  1364. X}
  1365. X
  1366. Xvoid
  1367. Xnull()
  1368. X{
  1369. X}
  1370. X
  1371. X
  1372. Xposition_current()
  1373. X{
  1374. X    int pos;
  1375. X
  1376. X    if (!m_fi)
  1377. X    return(0);
  1378. X    if (Current >= 0) {
  1379. X    pos = Entry[Current].fpos;
  1380. X    if (fseek (m_fi, pos, 0) < 0 || ftell(m_fi) != pos)
  1381. X        puts ("ERROR: Cannot position file to message");
  1382. X    } else {
  1383. X    fseek (m_fi, 0, 0);
  1384. X    }
  1385. X}
  1386. X
  1387. X
  1388. Xskip_to_data(fi)
  1389. XFILE *fi;
  1390. X{
  1391. X    static char buf[MAXFIELDSIZE];
  1392. X
  1393. X    while (fgets (buf, MAXFIELDSIZE, fi) != NULL) {
  1394. X    if (*buf == '\n')
  1395. X        return (1);
  1396. X    }
  1397. X    return (-1);
  1398. X}
  1399. X
  1400. X
  1401. Xchar *
  1402. Xget_field(str)
  1403. Xchar *str;
  1404. X{
  1405. X    int i, entry = Current;
  1406. X    int len = strlen(str);
  1407. X
  1408. X    if (Current < 0)
  1409. X    return("");
  1410. X    i = get_extra (str);
  1411. X    if (i >= 0)
  1412. X    return (Entry[entry].fields[i]);
  1413. X    if (m_fi == NULL)
  1414. X    return ("");
  1415. X    fseek (m_fi, Entry[entry].fpos, 0);
  1416. X    while (fgets (Buf, MAXFIELDSIZE, m_fi) != NULL) {
  1417. X    if (isfrom (Buf))
  1418. X        break;
  1419. X    if (strncmp (Buf, str, len) == 0) {
  1420. X        Buf[strlen(Buf) - 1] = '\0';
  1421. X        compile_field(Buf, m_fi);
  1422. X        return (next_word (Buf));
  1423. X    }
  1424. X    }
  1425. X    return ("");
  1426. X}
  1427. X
  1428. X
  1429. Xcompile_field(buf, fi)
  1430. Xchar *buf;
  1431. XFILE *fi;
  1432. X{
  1433. X    int len, acc, pos;
  1434. X
  1435. X    acc = 0;
  1436. X    buf += strlen (buf) + 1;
  1437. X    pos = ftell (fi);
  1438. X    while (fgets (buf, MAXFIELDSIZE - acc, fi) != NULL) {
  1439. X    if (*buf == ' ' || *buf == 9) {
  1440. X        *(buf - 1) = '\n';
  1441. X        len = strlen (buf) - 1;
  1442. X        *(buf + len) = '\0';
  1443. X        buf += len;
  1444. X        acc += len + 2;
  1445. X        if (acc > MAXFIELDSIZE - 10) {
  1446. X        printf ("Warning: Field size beyond %d bytes\n", MAXFIELDSIZE);
  1447. X        sleep (2);
  1448. X        return (1);
  1449. X        }
  1450. X    } else {
  1451. X        *buf = '\0';
  1452. X        fseek (fi, pos, 0);
  1453. X        return (1);
  1454. X    }
  1455. X    pos = ftell (fi);
  1456. X    }
  1457. X    fseek (fi, pos, 0);
  1458. X}
  1459. X
  1460. X
  1461. Xisfrom(str)
  1462. Xregister char *str;
  1463. X{
  1464. X    static char from[] = {"From "};
  1465. X    register int i = 0;
  1466. X
  1467. X    while (i < 5) {
  1468. X    if (*str++ != from[i++])
  1469. X        return (0);
  1470. X    }
  1471. X    return (1);
  1472. X}
  1473. X
  1474. X
  1475. Xxstrncmp (src, dest, len)
  1476. Xregister char *src, *dest;
  1477. Xregister int len;
  1478. X{
  1479. X    while (--len >= 0) {
  1480. X    if ((*src & 0x1f) != (*dest & 0x1f)) {
  1481. X        if ((*src & 0x1f) < (*dest & 0x1f))
  1482. X        return (-1);
  1483. X        return (1);
  1484. X    }
  1485. X    ++src; ++dest;
  1486. X    }
  1487. X    return (0);
  1488. X}
  1489. X
  1490. X
  1491. X
  1492. Xchar *
  1493. Xnext_word(str)
  1494. Xregister char *str;
  1495. X{
  1496. X    while (*str  &&  *str != ' '  && *str != 9)
  1497. X    ++str;
  1498. X    while (*str  &&  (*str == ' ' || *str == 9))
  1499. X    ++str;
  1500. X    return (str);
  1501. X}
  1502. X
  1503. Xvoid
  1504. Xdone(n)
  1505. X{
  1506. X    char scr[64];
  1507. X
  1508. X    push_break();
  1509. X    sprintf (scr, "t:dmail%d", getpid());
  1510. X    unlink (scr);
  1511. X    sprintf (scr, "t:dmt%d", getpid());
  1512. X    unlink (scr);
  1513. X    unlink ("#");
  1514. X    exit (n);
  1515. X}
  1516. X
  1517. Xvoid
  1518. Xfix_globals()
  1519. X{
  1520. X    char *ptr;
  1521. X
  1522. X    push_break();
  1523. X    S_page = (ptr = get_var (LEVEL_SET, "page")) ?
  1524. X        ((*ptr) ? atoi (ptr) : 24) : -1;
  1525. X    if (S_page > 0  && (S_page -= 4) < 0)
  1526. X    S_page = 1;
  1527. X
  1528. X    S_sendmail = (ptr = get_var (LEVEL_SET, "sendmail")) ? ptr : GetConfigProgram(SENDMAIL);
  1529. X    S_novibreak= (ptr = get_var (LEVEL_SET, "vibreak")) ? 0 : 1;
  1530. X    S_verbose  = (ptr = get_var (LEVEL_SET, "verbose")) ? 1 : 0;
  1531. X    S_ask      = (ptr = get_var (LEVEL_SET, "ask")) ? 1 : 0;
  1532. X    S_archive  = (ptr = get_var (LEVEL_SET, "archive")) ? 1 : 0;
  1533. X    if (S_archive && *ptr == '\0')
  1534. X    S_archive = 0;
  1535. X    pop_break();
  1536. X}
  1537. X
  1538. X
  1539. X_pager(str, nl)
  1540. Xchar *str;
  1541. Xint nl;
  1542. X{
  1543. X    static int count;
  1544. X    static FILE *fi;
  1545. X    static char buf[1024];
  1546. X#ifdef UNIX
  1547. X    char *ptr;
  1548. X#endif
  1549. X
  1550. X    if (str == 0) {
  1551. X    switch (S_page) {
  1552. X    case -1:
  1553. X        count = 0;
  1554. X        return (1);
  1555. X    case 0:
  1556. X#ifdef UNIX
  1557. X        ptr = get_var (LEVEL_SET, "page");
  1558. X        fi = popen (ptr, "w");
  1559. X        if (fi == NULL) {
  1560. X        count = 0;
  1561. X        printf ("CANNOT RUN PAGER PROGRAM: %s\n", ptr);
  1562. X        } else {
  1563. X        count = -1;
  1564. X        }
  1565. X#else
  1566. X        count = 0;
  1567. X        fi = stdout;
  1568. X#endif
  1569. X        return (1);
  1570. X    default:
  1571. X        count = 0;
  1572. X        return (1);
  1573. X    }
  1574. X    }
  1575. X    if ((long)str == -1) {
  1576. X#ifdef UNIX
  1577. X    if (fi != NULL) {
  1578. X        pclose (fi);
  1579. X        fi = NULL;
  1580. X    }
  1581. X#else
  1582. X    fi = NULL;
  1583. X#endif
  1584. X    return (1);
  1585. X    }
  1586. X    if (count < 0) {
  1587. X    fputs (str, fi);
  1588. X    while (nl--)
  1589. X        fputs ("\n", fi);
  1590. X    } else {
  1591. X    fputs (str, stdout);
  1592. X    while (nl--) {
  1593. X        fputs ("\n", stdout);
  1594. X        ++count;
  1595. X    }
  1596. X#ifdef AMIGA
  1597. X    fflush(stdout);
  1598. X#endif
  1599. X    while (*str) {
  1600. X        if (*str++ == '\n')
  1601. X        ++count;
  1602. X    }
  1603. X    if (S_page > 0  &&  S_page <= count) {
  1604. X        count = 0;
  1605. X        puts ("\n-- more --");
  1606. X        gets(buf);
  1607. X    }
  1608. X    }
  1609. X}
  1610. X
  1611. END_OF_FILE
  1612. if test 5006 -ne `wc -c <'uucp2/src/dmail/sub.c'`; then
  1613.     echo shar: \"'uucp2/src/dmail/sub.c'\" unpacked with wrong size!
  1614. fi
  1615. # end of 'uucp2/src/dmail/sub.c'
  1616. fi
  1617. if test -f 'uucp2/src/lib/alias.c' -a "${1}" != "-c" ; then 
  1618.   echo shar: Will not clobber existing file \"'uucp2/src/lib/alias.c'\"
  1619. else
  1620. echo shar: Extracting \"'uucp2/src/lib/alias.c'\" \(5044 characters\)
  1621. sed "s/^X//" >'uucp2/src/lib/alias.c' <<'END_OF_FILE'
  1622. X
  1623. X/*
  1624. X *  ALIAS.C
  1625. X *
  1626. X *  $Header: Beta:src/uucp/src/lib/RCS/alias.c,v 1.1 90/02/02 12:08:24 dillon Exp Locker: dillon $
  1627. X *
  1628. X *  (C) Copyright 1989-1990 by Matthew Dillon,  All Rights Reserved.
  1629. X *
  1630. X *  Interpret UULIB:Aliases file.  To save space we do not load
  1631. X *  the entire file, just sections on demand.
  1632. X *
  1633. X *  #    = comment
  1634. X *  id: name [, name...]
  1635. X *
  1636. X *  name is a user name, path, or |filter, or quoted name.  Example,
  1637. X *  "|more" or "|rnews"
  1638. X */
  1639. X
  1640. X#include <stdio.h>
  1641. X#include <stdlib.h>
  1642. X#include <fcntl.h>
  1643. X#include <time.h>
  1644. X#include "config.h"
  1645. X
  1646. X#include "log.h"
  1647. X
  1648. X#define HASHSIZE    256
  1649. X#define HASHMASK    (HASHSIZE-1)
  1650. X
  1651. X#define HF_TERM     0x01    /*    terminator name     */
  1652. X#define HF_ALIAS    0x02    /*    alias            */
  1653. X#define HF_LOADED   0x04    /*    def loaded        */
  1654. X
  1655. Xtypedef struct Hash {
  1656. X    struct Hash *Next;
  1657. X    short   NumAlias;    /*  # of aliases    */
  1658. X    short   Flags;
  1659. X    char    *Name;    /*  aliased user name    */
  1660. X    union {
  1661. X    struct Hash    **Alias;    /*  list of aliases       */
  1662. X    long    Offset;     /*    offset into file    */
  1663. X    } u;
  1664. X} Hash;
  1665. X
  1666. XPrototype void LoadAliases(void);
  1667. XPrototype void UserAliasList(const char *, void (*)(const char *));
  1668. X
  1669. XLocal Hash *FindHashObject(const char *);
  1670. XLocal void LoadHashObject(Hash *);
  1671. XLocal int  HashFunc(const char *);
  1672. X
  1673. X
  1674. Xstatic Hash    *HashTab[HASHSIZE];
  1675. Xstatic char    Tmp[256];
  1676. X
  1677. Xvoid
  1678. XLoadAliases()
  1679. X{
  1680. X    FILE *fi = fopen(MakeConfigPath(UULIB, "Aliases"), "r");
  1681. X    short i;
  1682. X    short j;
  1683. X    short k;
  1684. X    short line = 0;
  1685. X    long newoffset = 0;
  1686. X    long offset;
  1687. X    Hash *h;
  1688. X    char *buf = Tmp;
  1689. X
  1690. X    if (fi == NULL) {
  1691. X    ulog(-1, "Can't open %s", MakeConfigPath(UULIB, "Aliases"));
  1692. X    return;
  1693. X    }
  1694. X    while (fgets(buf, 256, fi)) {
  1695. X    offset = newoffset;
  1696. X    newoffset = ftell(fi);
  1697. X    ++line;
  1698. X    for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i);
  1699. X    if (buf[i] == '#' || buf[i] == '\n')
  1700. X        continue;
  1701. X    for (j = i; buf[j] && buf[j] != ':'; ++j);
  1702. X    if (buf[j] == 0) {
  1703. X        ulog(-1, "No Colon %s line %d", MakeConfigPath(UULIB, "Aliases"), line);
  1704. X        continue;
  1705. X    }
  1706. X    buf[j] = 0;
  1707. X
  1708. X    k = HashFunc(buf + i);
  1709. X    h = malloc(sizeof(Hash));
  1710. X    h->Next = HashTab[k];
  1711. X    h->NumAlias = 0;
  1712. X    h->Flags = HF_ALIAS;
  1713. X    h->Name = malloc(strlen(buf+i) + 1);
  1714. X    h->u.Offset = offset + j + 1;
  1715. X    strcpy(h->Name, buf + i);
  1716. X
  1717. X    HashTab[k] = h;
  1718. X
  1719. X    /*
  1720. X     *  if trailing comma, list continues onto next line
  1721. X     */
  1722. X
  1723. X    for (;;) {
  1724. X        for (++j; buf[j]; ++j);
  1725. X        while (buf[j-1] == ' ' || buf[j-1] == 9 || buf[j-1] == '\n')
  1726. X        --j;
  1727. X        if (buf[j-1] != ',')
  1728. X        break;
  1729. X        if (fgets(buf, 256, fi) == NULL)
  1730. X        break;
  1731. X        newoffset = ftell(fi);
  1732. X        j = 0;
  1733. X    }
  1734. X    }
  1735. X    fclose(fi);
  1736. X}
  1737. X
  1738. Xstatic
  1739. XHash *
  1740. XFindHashObject(name)
  1741. Xconst char *name;
  1742. X{
  1743. X    short k = HashFunc(name);
  1744. X    Hash *h;
  1745. X
  1746. X    for (h = HashTab[k]; h; h = h->Next) {
  1747. X    if (strcmp(name, h->Name) == 0)
  1748. X        return(h);
  1749. X    }
  1750. X    return(NULL);
  1751. X}
  1752. X
  1753. Xstatic
  1754. Xvoid
  1755. XLoadHashObject(hash)
  1756. XHash *hash;
  1757. X{
  1758. X    FILE *fi = fopen(MakeConfigPath(UULIB, "Aliases"), "r");
  1759. X    char *buf = Tmp;
  1760. X    short i, j;
  1761. X    short c;
  1762. X    short numalloc = 4;
  1763. X    Hash **hv = malloc(sizeof(Hash *) * 4);
  1764. X    Hash *h;
  1765. X
  1766. X    if (fi == NULL) {
  1767. X    ulog(-1, "Can't open %s", MakeConfigPath(UULIB, "Aliases"));
  1768. X    return;
  1769. X    }
  1770. X
  1771. X    hash->Flags |= HF_LOADED;
  1772. X    fseek(fi, hash->u.Offset, 0);
  1773. X    while (fgets(buf, 256, fi)) {
  1774. X    i = 0;
  1775. X    c = 'x';
  1776. X
  1777. X    for (;;) {
  1778. X        while (buf[i] == ' ' || buf[i] == 9)
  1779. X        ++i;
  1780. X        if (buf[i] == 0 || buf[i] == '\n')
  1781. X        break;
  1782. X
  1783. X        for (j = i; buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9 && buf[j] != ','; ++j) {
  1784. X        if (buf[j] == '\"') {
  1785. X            i = j + 1;
  1786. X            for (++j; buf[j] != '\n' && buf[j] != '\"'; ++j);
  1787. X            break;
  1788. X        }
  1789. X        }
  1790. X        c = buf[j];
  1791. X        buf[j] = 0;
  1792. X
  1793. X        if ((h = FindHashObject(buf + i)) == NULL) {
  1794. X        short k = HashFunc(buf + i);
  1795. X
  1796. X        h = malloc(sizeof(Hash));
  1797. X        h->Next = HashTab[k];
  1798. X        h->NumAlias = 0;
  1799. X        h->Flags = HF_TERM;
  1800. X        h->Name = malloc(strlen(buf + i) + 1);
  1801. X        h->u.Alias = NULL;
  1802. X        strcpy(h->Name, buf + i);
  1803. X
  1804. X        HashTab[k] = h;
  1805. X        }
  1806. X
  1807. X        if (hash->NumAlias == numalloc) {
  1808. X        Hash **hvo = hv;
  1809. X        short add = 4;
  1810. X
  1811. X        hv = malloc(sizeof(Hash *) * (numalloc + add));
  1812. X        movmem((char *)hvo, (char *)hv, sizeof(Hash *) * numalloc);
  1813. X        numalloc += add;
  1814. X        }
  1815. X        hv[hash->NumAlias++] = h;
  1816. X
  1817. X        i = j + 1;
  1818. X        if (c == '\"')
  1819. X        c = buf[i++];
  1820. X        if (c == '\n' || c == 0)
  1821. X        i = j;
  1822. X    }
  1823. X    if (c != ',')
  1824. X        break;
  1825. X    }
  1826. X    hash->u.Alias = hv;
  1827. X}
  1828. X
  1829. Xvoid
  1830. XUserAliasList(user, callback)
  1831. Xconst char *user;
  1832. Xvoid (*callback)(const char *);
  1833. X{
  1834. X    short i;
  1835. X    Hash *hash = FindHashObject(user);
  1836. X    static short stack;
  1837. X
  1838. X    if (++stack == 32) {
  1839. X    ulog(-1, "%s recursion near user %s", MakeConfigPath(UULIB, "Aliases"), user);
  1840. X    --stack;
  1841. X    return;
  1842. X    }
  1843. X
  1844. X    if (hash && (hash->Flags & HF_TERM) == 0) {
  1845. X    if ((hash->Flags & HF_LOADED) == 0)
  1846. X        LoadHashObject(hash);
  1847. X    for (i = 0; i < hash->NumAlias; ++i) {
  1848. X        Hash *h = hash->u.Alias[i];
  1849. X        UserAliasList(h->Name, callback);
  1850. X    }
  1851. X    } else {
  1852. X    (*callback)(user);
  1853. X    }
  1854. X    --stack;
  1855. X}
  1856. X
  1857. Xstatic int
  1858. XHashFunc(str)
  1859. Xconst char *str;
  1860. X{
  1861. X    unsigned long v = 0x14FBA5C3;
  1862. X    while (*str) {
  1863. X    v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
  1864. X    ++str;
  1865. X    }
  1866. X    return((int)(v & HASHMASK));
  1867. X}
  1868. X
  1869. END_OF_FILE
  1870. if test 5044 -ne `wc -c <'uucp2/src/lib/alias.c'`; then
  1871.     echo shar: \"'uucp2/src/lib/alias.c'\" unpacked with wrong size!
  1872. fi
  1873. # end of 'uucp2/src/lib/alias.c'
  1874. fi
  1875. if test -f 'uucp2/src/news/postnews.c.OLD' -a "${1}" != "-c" ; then 
  1876.   echo shar: Will not clobber existing file \"'uucp2/src/news/postnews.c.OLD'\"
  1877. else
  1878. echo shar: Extracting \"'uucp2/src/news/postnews.c.OLD'\" \(4283 characters\)
  1879. sed "s/^X//" >'uucp2/src/news/postnews.c.OLD' <<'END_OF_FILE'
  1880. X
  1881. X/*
  1882. X *  PostNews.c
  1883. X *
  1884. X *  Copyright 1988 by William Loftus.  All rights reserved.
  1885. X *
  1886. X *  Version 0.60 Beta
  1887. X *
  1888. X *  $Header: Beta:src/uucp/src/News060/postnews.c,v 1.1 90/02/02 11:44:07 dillon Exp Locker: dillon $
  1889. X */
  1890. X
  1891. X#include <time.h>
  1892. X#include <stdio.h>
  1893. X#include <stdlib.h>
  1894. X#include "log.h"
  1895. X#include "version.h"
  1896. X
  1897. XIDENT(".02");
  1898. X
  1899. Xchar *UserName;
  1900. Xchar *NodeName;
  1901. Xchar *RealName;
  1902. Xchar *NewsEditor;
  1903. Xchar *DomainName;
  1904. Xchar to_buf[128];
  1905. Xchar grp_buf[128];
  1906. Xchar dist_buf[128];
  1907. Xchar subject_buf[128];
  1908. Xchar *temp_file_name;
  1909. X
  1910. Xint seq;
  1911. X
  1912. Xchar *NewsFeed;
  1913. X
  1914. Xchar cmd[128];
  1915. Xchar path[128];
  1916. Xchar signature[121];
  1917. X
  1918. Xvoid read_ctl();
  1919. Xvoid GetTo();
  1920. Xvoid GetDist();
  1921. Xvoid GetSubject();
  1922. Xvoid GetMessage();
  1923. Xvoid BuildRnews();
  1924. Xvoid Signature();
  1925. Xvoid PromptGet();
  1926. Xchar *TmpFileName();
  1927. Xchar *FindConfig();
  1928. X
  1929. Xvoid
  1930. Xerrormsg (msg, ...)
  1931. Xchar *msg;
  1932. X{
  1933. X    printf(msg);
  1934. X}
  1935. X
  1936. X
  1937. Xvoid
  1938. Xmain()
  1939. X{
  1940. X    temp_file_name = TmpFileName(MakeConfigPath(UUSPOOL, "news"));
  1941. X
  1942. X    LogProgram = "PostNews";
  1943. X
  1944. X    UserName = FindConfig("UserName");
  1945. X    NodeName = FindConfig("NodeName");
  1946. X    NewsFeed = FindConfig("NewsFeed");
  1947. X    NewsEditor=FindConfig("NewsEditor");
  1948. X    RealName = FindConfig("RealName");
  1949. X    DomainName=FindConfig("DomainName");
  1950. X
  1951. X    if (UserName == NULL || NodeName == NULL || NewsFeed == NULL ||
  1952. X    NewsEditor==NULL || RealName == NULL || DomainName == NULL)
  1953. X    {
  1954. X    printf("UULIB:Config incomplete, missing one or more of:\n");
  1955. X    printf("    UserName, NodeName, DomainName, NewsFeed, NewsEditor, RealName\n");
  1956. X    exit(1);
  1957. X    }
  1958. X
  1959. X    GetTo();
  1960. X    GetDist();
  1961. X    GetSubject();
  1962. X    GetMessage();
  1963. X    BuildRnews();
  1964. X}
  1965. X
  1966. Xvoid
  1967. XGetTo()
  1968. X{
  1969. X    PromptGet("Newsgroup(s): ", 0, grp_buf, sizeof(grp_buf), stdin);
  1970. X}
  1971. X
  1972. Xvoid
  1973. XGetDist()
  1974. X{
  1975. X    FILE *fd;
  1976. X    char  buf[128];
  1977. X
  1978. X    if (!(fd = fopen(MakeConfigPath(UULIB, "news.distribution"), "r"))) {
  1979. X    errormsg("Can't Find news.distribution file");
  1980. X    exit(3);
  1981. X    }
  1982. X
  1983. X    while (fgets(buf, sizeof buf, fd)) {
  1984. X    printf("%s", buf);
  1985. X    }
  1986. X
  1987. X    PromptGet("Distribution: ", 0, dist_buf, sizeof(dist_buf), stdin);
  1988. X}
  1989. X
  1990. Xvoid
  1991. XGetSubject()
  1992. X{
  1993. X    PromptGet("Subject: ", 1, subject_buf, sizeof(subject_buf), stdin);
  1994. X}
  1995. X
  1996. Xvoid
  1997. XGetMessage()
  1998. X{
  1999. X    FILE *fp;
  2000. X    time_t t;
  2001. X
  2002. X    seq = GetSequence(4);
  2003. X
  2004. X    fp = fopen(temp_file_name, "w");
  2005. X
  2006. X    if (fp) {
  2007. X    time(&t);
  2008. X    fprintf(fp,"Relay-Version: X-AmigaNEWS version 0.60 BETA; site %s%s\n", NodeName, DomainName);
  2009. X    fprintf(fp,"Posting-Version: X-AmigaNEWS version 0.60 BETA; site %s%s\n", NodeName, DomainName);
  2010. X    fprintf(fp,"Path: %s!%s\n", NodeName, UserName);
  2011. X    fprintf(fp,"From: %s@%s%s (%s)\n", UserName, NodeName, DomainName, RealName);
  2012. X    fprintf(fp,"Newsgroups: %s", grp_buf);
  2013. X    fprintf(fp,"Subject: %s", subject_buf);
  2014. X    fprintf(fp,"Message-Id: <%05d.AA%05d@%s%s>\n", seq, seq, NodeName, DomainName);
  2015. X    fprintf(fp,"Date: %s", ctime(&t));
  2016. X    fprintf(fp,"Followup-To: %s", grp_buf);
  2017. X    fprintf(fp,"Expires: \n");
  2018. X    fprintf(fp,"Keywords: \n");
  2019. X    fprintf(fp,"Distribution: %s\n\n", dist_buf);
  2020. X
  2021. X    fclose(fp);
  2022. X    } else {
  2023. X    errormsg("Can't open temp file %s\n", temp_file_name);
  2024. X    exit(1);
  2025. X    }
  2026. X
  2027. X    sprintf(cmd,"%s %s", NewsEditor, temp_file_name);
  2028. X    system(cmd);
  2029. X
  2030. X    printf("Append .signature file? [y/n] ");
  2031. X    fgets(signature, sizeof signature, stdin);
  2032. X    if ((signature[0] | 0x20) != 'n') {
  2033. X    Signature();
  2034. X    printf(".signature file appended.\n");
  2035. X    }
  2036. X}
  2037. X
  2038. Xvoid
  2039. XBuildRnews()
  2040. X{
  2041. X    NewsFeed[7] = '\0';
  2042. X
  2043. X    sprintf(cmd, "UUX %s \"%s!rnews\"", temp_file_name, NewsFeed);
  2044. X    system(cmd);
  2045. X    remove(temp_file_name);
  2046. X}
  2047. X
  2048. X/*
  2049. X * Read the control file and grab a few parameters.
  2050. X */
  2051. X
  2052. Xvoid
  2053. XSignature()
  2054. X{
  2055. X    FILE *fp;
  2056. X    FILE *sf;
  2057. X    char buff[128];
  2058. X
  2059. X    fp = fopen(temp_file_name, "a");  /* should already exist!! */
  2060. X
  2061. X    if (!fp) {
  2062. X    errormsg("Can't open temp file--%s\n", temp_file_name);
  2063. X    exit(1);
  2064. X    }
  2065. X
  2066. X    fprintf(fp, "\n--\n");
  2067. X
  2068. X    sf = fopen(MakeConfigPath(UULIB, ".signature"), "r");
  2069. X
  2070. X    if (sf) {
  2071. X    while (NULL != fgets(buff, sizeof buff, sf)) {
  2072. X        fprintf(fp, "%s", buff);
  2073. X    }
  2074. X    fclose(sf);
  2075. X    } else {
  2076. X    errormsg("Can't open .signature file\n");
  2077. X    }
  2078. X    fclose(fp);
  2079. X}
  2080. X
  2081. Xvoid
  2082. XPromptGet(prompt, loop, buf, bufsize, fin)
  2083. Xchar *prompt;
  2084. Xchar *buf;
  2085. XFILE *fin;
  2086. X{
  2087. X    short i;
  2088. X
  2089. X    do {
  2090. X    printf("%s", prompt);
  2091. X    fflush(stdout);
  2092. X    if (fgets(buf, bufsize, fin) == NULL)
  2093. X        break;
  2094. X    for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i);
  2095. X    if (buf[i] != '\n')
  2096. X        break;
  2097. X    } while (loop);
  2098. X}
  2099. X
  2100. X
  2101. END_OF_FILE
  2102. if test 4283 -ne `wc -c <'uucp2/src/news/postnews.c.OLD'`; then
  2103.     echo shar: \"'uucp2/src/news/postnews.c.OLD'\" unpacked with wrong size!
  2104. fi
  2105. # end of 'uucp2/src/news/postnews.c.OLD'
  2106. fi
  2107. if test -f 'uucp2/src/sendmail/domain.c' -a "${1}" != "-c" ; then 
  2108.   echo shar: Will not clobber existing file \"'uucp2/src/sendmail/domain.c'\"
  2109. else
  2110. echo shar: Extracting \"'uucp2/src/sendmail/domain.c'\" \(4627 characters\)
  2111. sed "s/^X//" >'uucp2/src/sendmail/domain.c' <<'END_OF_FILE'
  2112. X
  2113. X/*
  2114. X *  DOMAIN.C
  2115. X *
  2116. X *  $Header: Beta:src/uucp/src/sendmail/RCS/domain.c,v 1.1 90/02/02 12:14:59 dillon Exp Locker: dillon $
  2117. X *
  2118. X *  (C) Copyright 1989-1990 by Matthew Dillon,  All Rights Reserved.
  2119. X *
  2120. X *  Given the first machine in a path scan the domain list and
  2121. X *  return the type, class, and address of the resource entry.
  2122. X *
  2123. X *  AUTOMATIC HACKS:    scans L.sys file and automatically deals
  2124. X *            with machine[.UUCP] domain, returning
  2125. X *            Type=MD Class=UU Addr=machine.UUCP
  2126. X */
  2127. X
  2128. X#include "defs.h"
  2129. X
  2130. XPrototype DomainLookup(char *, int, char *, char *, char *);
  2131. XPrototype CompareDomain(char **, short, char **, short);
  2132. X
  2133. Xextern char *DefaultNode;
  2134. Xextern char *NodeName;
  2135. X
  2136. Xint
  2137. XDomainLookup(name, len, tb, cb, ab)
  2138. Xchar *name;
  2139. Xint len;
  2140. Xchar *tb;
  2141. Xchar *cb;
  2142. Xchar *ab;
  2143. X{
  2144. X    char *dary[16];
  2145. X    char *tmp = malloc(len + 1);
  2146. X    char *tbase = tmp;
  2147. X    short b, i;
  2148. X    short di;
  2149. X    FILE *fi;
  2150. X    short level;        /*    best domain level found so far */
  2151. X    static char buf[256];
  2152. X
  2153. X    for (b = i = di = 0; i < len && name[i] != '!'; ++i) {
  2154. X    if (name[i] == '.') {
  2155. X        if (di == sizeof(dary)/sizeof(dary[0]) - 1) {
  2156. X        ulog(-1, "DomainLookup, too many domains! %s", name);
  2157. X        break;
  2158. X        }
  2159. X        strncpy(tmp, name + b, i - b);
  2160. X        tmp[i - b] = 0;
  2161. X        dary[di] = tmp;
  2162. X        tmp += i - b + 1;
  2163. X        b = i + 1;
  2164. X        ++di;
  2165. X    }
  2166. X    }
  2167. X    strncpy(tmp, name + b, i - b);
  2168. X    tmp[i - b] = 0;
  2169. X    dary[di++] = tmp;
  2170. X
  2171. X#ifdef NOTDEF
  2172. X    {
  2173. X    short i;
  2174. X    for (i = 0; i < di; ++i)
  2175. X        printf("XX '%s'\n", dary[i]);
  2176. X    }
  2177. X#endif
  2178. X
  2179. X    /*
  2180. X     *    Check local mail
  2181. X     */
  2182. X
  2183. X    level = 0;
  2184. X
  2185. X    if (strcmpi(dary[0], NodeName) == 0) {
  2186. X    strcpy(tb, "--");   /*  not used by caller */
  2187. X    strcpy(cb, "LL");
  2188. X    strcpy(ab, "--");
  2189. X    level = 1;
  2190. X    }
  2191. X
  2192. X    if (level == 0 && (fi = fopen(MakeConfigPath(UULIB, "Domain"), "r"))) {
  2193. X    while (fgets(buf, sizeof(buf), fi)) {
  2194. X        short l2;
  2195. X        short di2 = 0;
  2196. X        char *dary2[16];
  2197. X
  2198. X        if (buf[0] == ' ' || buf[0] == 9 || buf[0] == '\n' || buf[0] == '#')
  2199. X        continue;
  2200. X        for (b = i = 0; buf[i] && buf[i] != ' ' && buf[i] != 9; ++i) {
  2201. X        if (buf[i] == '.') {
  2202. X            if (di2 == sizeof(dary2)/sizeof(dary2[0]) - 1) {
  2203. X            ulog(-1, "%s, entry has too many subdomains: %s", MakeConfigPath(UULIB, "Domain"), buf);
  2204. X            break;
  2205. X            }
  2206. X            dary2[di2++] = buf + b;
  2207. X            buf[i] = 0;
  2208. X            b = i + 1;
  2209. X        }
  2210. X        }
  2211. X        buf[i] = 0;
  2212. X        dary2[di2++] = buf + b;
  2213. X
  2214. X        buf[i] = 0;     /*  get domain name/wildcard        */
  2215. X
  2216. X        l2 = CompareDomain(dary, di, dary2, di2);
  2217. X
  2218. X#ifdef NOTDEF
  2219. X        {
  2220. X        short i;
  2221. X        printf("\nres %d\n", l2);
  2222. X        for (i = 0; i < di; ++i)
  2223. X            printf("#1 %s\n", dary[i]);
  2224. X        for (i = 0; i < di2; ++i)
  2225. X            printf("#2 %s\n", dary2[i]);
  2226. X        }
  2227. X#endif
  2228. X
  2229. X        if (l2 > level) {   /*  better domain then what we have     */
  2230. X        sscanf(buf + i + 1, "%s %s %s", tb, cb, ab);
  2231. X        level = l2;
  2232. X        }
  2233. X    }
  2234. X    fclose(fi);
  2235. X    }
  2236. X
  2237. X    /*
  2238. X     *    Couldn't find the appropriate domain entry, check L.sys
  2239. X     *    OR domain entry is a forwarder, check L.sys
  2240. X     */
  2241. X
  2242. X    if (strcmp(tb, "MF") == 0 || level == 0) {
  2243. X    if (fi = fopen(MakeConfigPath(UULIB, "L.sys"), "r")) {
  2244. X        while (fgets(buf, sizeof(buf), fi)) {
  2245. X        if (buf[0] == ' ' || buf[0] == 9 || buf[0] == '#' || buf[0] == '\n')
  2246. X            continue;
  2247. X        for (i = 0; buf[i] && buf[i] != ' ' && buf[i] != 9; ++i);
  2248. X        buf[i] = 0;
  2249. X        if (strcmpi(dary[0], buf) == 0) {
  2250. X            strcpy(tb, "MD");
  2251. X            strcpy(cb, "UU");
  2252. X            strcpy(ab, buf);
  2253. X            strcat(ab, ".UUCP");
  2254. X            level = 1;
  2255. X            break;
  2256. X        }
  2257. X        }
  2258. X        fclose(fi);
  2259. X    }
  2260. X    }
  2261. X
  2262. X    /*
  2263. X     *    Couldn't find nothing, use DefaultNode
  2264. X     */
  2265. X
  2266. X    if (level == 0) {
  2267. X    ulog(-1, "Warning, unable to interpret addr %s, using DefaultNode", name);
  2268. X    if (DefaultNode == NULL) {
  2269. X        ulog(-1, "Error, DefaultNode must exist if no Domain file");
  2270. X        printf("ERROR, no entry in Domain, L.sys, and\n");
  2271. X        printf("no DefaultNode config entry for %s\n", name);
  2272. X        puts("cannot send mail");
  2273. X        free(tbase);
  2274. X        return(0);
  2275. X    }
  2276. X    strcpy(tb, "MF");
  2277. X    strcpy(cb, "UU");
  2278. X    strcpy(ab, DefaultNode);
  2279. X    level = 1;
  2280. X    }
  2281. X    free(tbase);
  2282. X    return(level > 0);
  2283. X}
  2284. X
  2285. X/*
  2286. X *  Compares a broken up address with a domain entry (buf).
  2287. X */
  2288. X
  2289. Xint
  2290. XCompareDomain(da1, di1, da2, di2)
  2291. Xchar **da1;
  2292. Xshort di1;
  2293. Xchar **da2;
  2294. Xshort di2;
  2295. X{
  2296. X    short i, j;
  2297. X    short level = 0;
  2298. X
  2299. X    for (i = di1 - 1, j = di2 - 1; i >= 0 && j >= 0; --i, --j) {
  2300. X    if (da2[j][0] == '*') {
  2301. X        ++level;
  2302. X        if (i && j == 0)    /*  so loop does not terminate  */
  2303. X        ++j;
  2304. X        continue;
  2305. X    }
  2306. X    if (strcmpi(da1[i], da2[j]) == 0)
  2307. X        level += 2;
  2308. X    else {
  2309. X        if (j + 1 < di2 && da2[j+1][0] == '*') {
  2310. X        ++level;
  2311. X        ++j;
  2312. X        } else
  2313. X        return(0);
  2314. X    }
  2315. X    }
  2316. X    if (j >= 0)         /*  didn't exhaust domain entry */
  2317. X    return(0);
  2318. X    return((int)level);
  2319. X}
  2320. X
  2321. END_OF_FILE
  2322. if test 4627 -ne `wc -c <'uucp2/src/sendmail/domain.c'`; then
  2323.     echo shar: \"'uucp2/src/sendmail/domain.c'\" unpacked with wrong size!
  2324. fi
  2325. # end of 'uucp2/src/sendmail/domain.c'
  2326. fi
  2327. if test -f 'uucp2/src/unix/unshar.c' -a "${1}" != "-c" ; then 
  2328.   echo shar: Will not clobber existing file \"'uucp2/src/unix/unshar.c'\"
  2329. else
  2330. echo shar: Extracting \"'uucp2/src/unix/unshar.c'\" \(6759 characters\)
  2331. sed "s/^X//" >'uucp2/src/unix/unshar.c' <<'END_OF_FILE'
  2332. X
  2333. X/*
  2334. X *  UNSHAR.C
  2335. X *
  2336. X *  $Header: Beta:src/uucp/src/compress/RCS/unshar.c,v 1.1 90/02/02 11:48:02 dillon Exp Locker: dillon $
  2337. X *
  2338. X *    unshar    -- undo a shell archive file
  2339. X *    (C) Copyright June 4 1987 by Craig Norborg
  2340. X *    Permission given to use this code in any form as long as it is
  2341. X *    not sold or marketed in any form without the written permission
  2342. X *    of its author.    Removal of this copyright notice is expressly
  2343. X *    forbidden as well as any alteration of it.
  2344. X */
  2345. X/*
  2346. X *    Here is a small unshar program written to be as portable as possible.
  2347. X *    It was written under Aztec C on an Amiga and tested on a VAX 11/780,
  2348. X *    pdp11/70 and a Sequent Balance 21000.  Any bug reports or enhancements
  2349. X *    should be reported to the author.  Some further enhancements may
  2350. X *    include the correct handling of sub-directories and the handling of
  2351. X *    btoa/atob type shars.  If you find a type of shar that this code
  2352. X *    does not work on, please send it to me, doc@j.cc.purdue.edu.
  2353. X */
  2354. X
  2355. X#include <stdio.h>
  2356. X#include <ctype.h>
  2357. X#include <string.h>
  2358. X#include "version.h"
  2359. X
  2360. XIDENT(".00");
  2361. X
  2362. X#ifdef unix
  2363. X#include <sys/file.h>
  2364. X#endif unix
  2365. X#ifdef AMIGA
  2366. X#define F_OK    0
  2367. X#endif AMIGA
  2368. X
  2369. X#define BUFSIZE 512        /* Max length of an input line */
  2370. X#define STRLEN    25        /* Max length of a file name or delimiter */
  2371. X#define CAT    "cat"           /* The name of the 'cat' program */
  2372. X#define SED    "sed"           /* The name of the 'sed' program */
  2373. X#define TEST    "if test"       /* Leader for test types */
  2374. X
  2375. X/*
  2376. X * This is a small routine that given the beginning of a quoted, backslashed
  2377. X * or just plain string, will return it in a given buffer.
  2378. X */
  2379. Xvoid
  2380. Xcopystring(source, dest)
  2381. Xchar *source, *dest;
  2382. X{
  2383. X    register int i = 0;
  2384. X    char c;
  2385. X
  2386. X    if ('\'' == *source || '\"' == *source) {/* Is it a quoted string? */
  2387. X        c = *source;
  2388. X        while (c != *++source)
  2389. X            dest[i++] = *source;
  2390. X        source++;
  2391. X    } else if ('\\' == *source) {                   /* Is it a backslashed string? */
  2392. X        while (!isspace(*++source))
  2393. X            dest[i++] = *source;
  2394. X    } else {                                /* Just a string */
  2395. X        while (!isspace(*source)) {
  2396. X            dest[i++] = *source;
  2397. X            source++;
  2398. X        }
  2399. X    }
  2400. X    dest[i] = '\0';
  2401. X}
  2402. X
  2403. Xvoid
  2404. Xwordcount(buf, filename, wc)
  2405. Xchar *buf, *filename;
  2406. Xint wc;
  2407. X{
  2408. X    if (wc != atoi(buf)) {
  2409. X        (void) printf("Error unsharing %s (wc should have been %d, but was %d)\n", filename, atoi(buf), wc);
  2410. X    }
  2411. X}
  2412. X
  2413. Xint
  2414. Xcheckfile(string)
  2415. Xchar *string;
  2416. X{
  2417. X    char filename[BUFSIZE];
  2418. X
  2419. X    while (0 != isspace(*string))
  2420. X        string++;
  2421. X
  2422. X    copystring(string, filename);
  2423. X    if (0 == access(filename, F_OK))
  2424. X        return 1;
  2425. X
  2426. X    return 0;
  2427. X}
  2428. X
  2429. X/*
  2430. X * This is a small routine that given a 'cat' or 'sed' string, will pull out
  2431. X * the end of file string and the file name
  2432. X */
  2433. Xvoid
  2434. Xgetendfile(line, end, file)
  2435. Xchar   *line,            /* The 'sed' or 'cat' string */
  2436. X       *end,            /* Place to store the end of file marker */
  2437. X       *file;            /* Place for the filename */
  2438. X{
  2439. X    char   *tmp;
  2440. X
  2441. X    /*
  2442. X     * This section of code finds the end of file string.  It assumes
  2443. X     * that the eof string is the string of characters immediately
  2444. X     * following the last '<' and that it has either a '\' preceding it
  2445. X     * or is surrounded by single quotes.
  2446. X     */
  2447. X    tmp = (char *) strrchr(line, '<');       /* Find the last '<' on the
  2448. X                                             * line */
  2449. X    while (isspace(*++tmp))
  2450. X        ;    /* Do nothing */
  2451. X    copystring(tmp, end);
  2452. X
  2453. X    /*
  2454. X     * This section of code finds the name of the file.  It assumes that
  2455. X     * the name of the file is the string immediately following the last
  2456. X     * '>' in the line
  2457. X     */
  2458. X    tmp = (char *) strrchr(line, '>');
  2459. X    while (isspace(*++tmp))
  2460. X        ;    /* Do Nothing */
  2461. X    copystring(tmp, file);
  2462. X
  2463. X#ifdef DEBUG
  2464. X    (void) printf("EOF = %s, FILE = %s\n", end, file);
  2465. X#endif DEBUG
  2466. X}
  2467. X
  2468. Xint
  2469. Xmain(argc, argv)
  2470. Xint    argc;
  2471. Xchar  **argv;
  2472. X{
  2473. X    FILE   *fp, *dfp;        /* input file pointer and dest file
  2474. X                     * pointer */
  2475. X    char    buf[BUFSIZE],        /* line buffer */
  2476. X        prefix[STRLEN],     /* SED leader if any */
  2477. X        endstring[STRLEN],    /* EOF marker */
  2478. X        filename[STRLEN];    /* file name */
  2479. X    int    infile = 0,            /* var to tell if we're in the middle of a
  2480. X                                 * file or not */
  2481. X        wc = 0,             /* variable to keep a word count */
  2482. X            fileexists = 0;     /* does the file exist? */
  2483. X
  2484. X    if (1 == argc) {        /* check usage */
  2485. X        (void) printf("usage: unshar <file>");
  2486. X    }
  2487. X    if (NULL == (fp = fopen(argv[1], "r"))) {
  2488. X        (void) printf("Error opening input file\n");
  2489. X        exit(1);
  2490. X    }
  2491. X    while (NULL != fgets(buf, BUFSIZE, fp)) {       /* while there are lines
  2492. X                             * to get */
  2493. X#ifdef DEBUG
  2494. X        puts(buf);
  2495. X#endif DEBUG
  2496. X
  2497. X        if (0 == infile) {      /* if we are not in the middle of a
  2498. X                     * file */
  2499. X            if ('#' == buf[0])      /* comment? */
  2500. X                continue;
  2501. X
  2502. X            /* Is this a CAT type shar? */
  2503. X            if (0 == strncmp(buf, CAT, strlen(CAT))) {
  2504. X                prefix[0] = '\0';
  2505. X                getendfile(buf, endstring, filename);
  2506. X                if (fileexists != 0) {
  2507. X                    fprintf(stderr, "File exists (%s), skipping\n", filename);
  2508. X                    fileexists = 0;
  2509. X                    continue;
  2510. X                }
  2511. X                if (NULL == (dfp = fopen(filename, "w"))) {
  2512. X                    (void) printf("Error opening output file %s\n", filename);
  2513. X                    exit(1);
  2514. X                }
  2515. X                (void) printf("Extracting %s ... ", filename);
  2516. X                (void) fflush(stdout);
  2517. X                infile = 1;
  2518. X                wc = 0;
  2519. X                continue;
  2520. X            }
  2521. X            /* Is it a SED type shar? */
  2522. X            if (0 == strncmp(buf, SED, strlen(SED))) {
  2523. X                register int i = 0, j = 0;
  2524. X
  2525. X                while ('^' != buf[i++])
  2526. X                    ;
  2527. X                while ('/' != buf[i]) {
  2528. X                    prefix[j++] = buf[i++];
  2529. X                }
  2530. X                prefix[j] = '\0';
  2531. X                getendfile(&buf[i], endstring, filename);
  2532. X                if (fileexists != 0) {
  2533. X                    fprintf(stderr, "File exists (%s), skipping\n", filename);
  2534. X                    fileexists = 0;
  2535. X                    continue;
  2536. X                }
  2537. X                if (NULL == (dfp = fopen(filename, "w"))) {
  2538. X                    (void) printf("Error opening output file %s\n", filename);
  2539. X                    exit(1);
  2540. X                }
  2541. X                (void) printf("Extracting %s ... ", filename);
  2542. X                (void) fflush(stdout);
  2543. X                infile = 1;
  2544. X                wc = 0;
  2545. X                continue;
  2546. X            }
  2547. X            /* Do we want to do a test of sorts on a file? */
  2548. X            if (0 == strncmp(buf, TEST, strlen(TEST))) {
  2549. X                register int i = 0;
  2550. X
  2551. X                while(!isdigit(buf[i]) && buf[i] != '-' && buf[i])
  2552. X                    i++;
  2553. X
  2554. X                if (0 != isdigit(buf[i])) {
  2555. X                    wordcount(&buf[i], filename, wc);
  2556. X                }
  2557. X
  2558. X                if ('f' == buf[++i]) {
  2559. X                    fileexists = checkfile(&buf[++i]);
  2560. X                }
  2561. X                continue;
  2562. X            }
  2563. X        } else {    /* We are in the middle of a file */
  2564. X
  2565. X            /* Are we at the end of this one? */
  2566. X            if (0 == strncmp(buf, endstring, strlen(endstring))) {
  2567. X                (void) printf("Done\n");
  2568. X                (void) fclose(dfp);
  2569. X                infile = 0;
  2570. X                continue;
  2571. X            }
  2572. X            /* No, then does it have a prefix? */
  2573. X            if ('\0' == prefix[0]) {
  2574. X                fputs(buf, dfp);
  2575. X                wc = wc + strlen(buf);
  2576. X            } else {
  2577. X
  2578. X                /*
  2579. X                 * If it does have a prefix, is there one on
  2580. X                 * this line?
  2581. X                 */
  2582. X                if (0 != strncmp(buf, prefix, strlen(prefix))) {
  2583. X                    fputs(buf, dfp);
  2584. X                } else {
  2585. X                    fputs(&buf[strlen(prefix)], dfp);
  2586. X                    wc = wc + strlen(buf) - strlen(prefix);
  2587. X                }
  2588. X            }
  2589. X        }
  2590. X    }
  2591. X    (void) printf("All Done!\n");
  2592. X    (void) fclose(fp);
  2593. X}
  2594. END_OF_FILE
  2595. if test 6759 -ne `wc -c <'uucp2/src/unix/unshar.c'`; then
  2596.     echo shar: \"'uucp2/src/unix/unshar.c'\" unpacked with wrong size!
  2597. fi
  2598. # end of 'uucp2/src/unix/unshar.c'
  2599. fi
  2600. echo shar: End of archive 5 \(of 12\).
  2601. cp /dev/null ark5isdone
  2602. MISSING=""
  2603. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  2604.     if test ! -f ark${I}isdone ; then
  2605.     MISSING="${MISSING} ${I}"
  2606.     fi
  2607. done
  2608. if test "${MISSING}" = "" ; then
  2609.     echo You have unpacked all 12 archives.
  2610.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2611. else
  2612.     echo You still need to unpack the following archives:
  2613.     echo "        " ${MISSING}
  2614. fi
  2615. ##  End of shell archive.
  2616. exit 0
  2617. -- 
  2618. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  2619. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  2620. Post requests for sources, and general discussion to comp.sys.amiga.
  2621.